import { MenuItemPoolItem } from "@/config/types";
import { GraphNode } from "@/modules/model/project/GraphNode";

import { treeForEach } from "@/util/common";
import { MetaclassType } from "@/constants/MetaclassType";
import { ActionKey } from "@/action/ActionKey";
import { MenuItem, ModelData } from "@/constants/types";
import { CoworkPackageStatus, PackageStatusObject } from "@/modules/model/project/ProjectConfig";
import { ModelFrom, ReadPermissionType, UsedStatus, ModelType, HiddenStatus, KeyboardEventArea, ProjectTab } from "@/constants/Enums";
import { modelService, projectService } from "@/modules/model/service";
import { coworkService } from "@/modules/cowork/service/CoworkService";
import { isShowShareValid } from "../../../panel/validConfig";
import { actionManager } from "@/action/ActionManager";
import treeContextMenuConfig from "@/config/treeContextMenuConfig.json";
// import { ModelType, UsedStatus, ModelFrom, HiddenStatus } from "@/constants/Enums";

/**
 * 收束树节点操作
 */
class TreeUtil {
  async getNodeContextMenu(node: GraphNode, commentLevel?: number): Promise<MenuItem[]> {
    let menu = (await node.getContextMenu()) as MenuItem[];
    console.log("getNodeContextMenu", menu);
    const menuItemMap: { [p: string]: any } = {};
    const copyNodes = app.global.copyPasteModel.copiedGraphNodes;
    const copyLibNodes = app.global.copyPasteModel.copiedLibraryNodes;
    treeForEach(menu, (menuItem: any) => {
      if (menuItem) {
        // 多选情况下，复制和剪切按钮先置灰
        if (app.activeProject!.nodePool.selectedNodeIds?.length > 1 && [ActionKey.copyNode, ActionKey.cutNode].includes(menuItem.value)) {
          menuItem.disabled = true;
        }
        // 匹配快捷键
        // const keyboard = Object.entries(ModelTreeKeyEvent).find(it => it[1] == menuItem?.value);
        const keyboard = actionManager.getFirstBindKey(menuItem.value, KeyboardEventArea.ModelTree);
        if (keyboard) {
          menuItem.keyboard = keyboard;
        }

        menuItemMap[menuItem.value] = menuItem;
        // 复制相关（bug-5281，根节点、edge右键无复制）
        if ([ActionKey.copyNode, ActionKey.cutNode].includes(menuItem.value)) {
          if (
            node.data.type == ModelType.Relation ||
            !node.parentId ||
            [ModelFrom.SYSTEM_PROFILE, ModelFrom.IMPORT_PROFIEL].includes(node.data.from)
          ) {
            menuItem.disabled = true;
          }
        }

        if (menuItem.value == ActionKey.pasteNode) {
          // 若未复制过元素，则粘贴置灰
          if (
            !copyNodes?.length ||
            [ModelFrom.SYSTEM_PROFILE, ModelFrom.IMPORT_PROFIEL].includes(node.data.from) ||
            copyNodes?.length > 1
          ) {
            menuItem.disabled = true;
          }
          if (copyLibNodes && copyLibNodes?.length > 0) {
            menuItem.disabled = false;
          }
        }

        if (menuItem.value === ActionKey.exportMd3) {
          if ([ModelFrom.SYSTEM_PROFILE, ModelFrom.IMPORT_PROFIEL].includes(node.data.from)) {
            menuItem.disabled = true;
          }
        }

        if (menuItem.value === ActionKey.importProject && app.activeProject?.config.online) {
          menuItem.disabled = true;
        }

        if (menuItem.value === ActionKey.editProfile) {
          const config = app.activeProject?.config;
          if (
            [ModelFrom.SYSTEM_PROFILE].includes(node.data.from) ||
            !config?.dependencies.find(dependency => dependency.profileName === node.data.name) ||
            config?.isProfile ||
            (config.online && !config.onlineConfig.packageStatus[config.rootId].CHECKED_IN)
          ) {
            menuItem.disabled = true;
          }
        }
        if ([ActionKey.setNodeInEdit, ActionKey.removeModel, ActionKey.exportMd3, ActionKey.exportProfile].includes(menuItem.value)) {
          if (app.activeProject?.config?.isProfile) {
            // 扩展包编辑，不允许修改正编辑的扩展包的名称
            const profileModelId = app.global.profileEditProjectIdMapModel.profileNameToProfileModelIdMap.get(
              app.activeProject?.config?.profileName
            ) as string;
            if (profileModelId === node.data.id) {
              menuItem.disabled = true;
            }
          }
        }
        if (app.activeProject?.config?.isProfile && node.data.metaclass === MetaclassType.Model) {
          // 扩展包编辑 根节点不允许新建xx
          if (
            [
              ActionKey.openCreateElement,
              ActionKey.openCreateDiagram,
              ActionKey.openCreateRelation,
              ActionKey.importProject,
              ActionKey.importRequirement,
              ActionKey.exportMd3
            ].includes(menuItem.value)
          ) {
            menuItem.disabled = true;
          }
        }
      }
    });
    // 获取导航子菜单
    const navTo = menu.find(item => item.value == ActionKey.navTo);
    if (navTo) {
      navTo.children = (await modelService.navTo(app.activeProject!.id, node.id, "")).map(model => {
        return {
          label: model.name,
          value: ActionKey.navTo,
          icon: model.icon,
          param: model,
          forbidTranslate: true
        };
      });
      if (!navTo.children || !navTo.children.length) {
        navTo.disabled = true;
      }
    }
    menu = await this.modifyCoworkMenu(menuItemMap, menu, node);
    menu = this.modifyPackageMenu(menuItemMap, menu, node);
    menu = this.modifySimulateMenu(menu, node);
    menu = this.setDisabled(menuItemMap, menu, node);
    menu = this.modifyLocateComment(menuItemMap, menu, commentLevel);
    await projectService.fillFmuModelMenu(menu, node.data.projectId, node.data.id, node.data.showAttribute?.stereotypes || []);
    this.modifyModelSharedMenu(menu, node);
    for (let m of app.moduleManager.moduleMap.values()) {
      menu = (await m.modifyGraphNodeContextMenu(node, menu)) as MenuItemPoolItem[];
    }
    // 批量操作下 菜单只有构造型、复制、剪切、删除
    if (app.activeProject!.nodePool.selectedNodeIds?.length > 1) {
      menu = menu.filter(item => treeContextMenuConfig.batchContextMenu.includes(item.value));
    }
    // const hasMlinkPlugin = app.global.activePlugins.find(i => i.key === 'M-Link');
    // if (hasMlinkPlugin) {
    //   menu = await this.modifyModelicaMenu(menuItemMap, menu, node);
    // }
    menu = this.modifyEncryptMenu(menuItemMap, menu, node);

    return menu;
  }

  async modifyCoworkMenu(menuItemMap: Record<string, MenuItem>, menuItems: MenuItem[], node: GraphNode) {
    if (
      !app.activeProject?.config.online ||
      [ModelFrom.SYSTEM_PROFILE, ModelFrom.IMPORT_PROFIEL].includes(node.data.from) ||
      app.activeProject!.ui.currentTab === ProjectTab.LibraryTree
    ) {
      menuItems = menuItems?.filter(item => item && item?.value !== "cooperation");
    } else {
      if (menuItemMap.cooperation) {
        menuItemMap.cooperation.disabled = false;
        const checkIn = menuItemMap.checkIn;
        const checkOut = menuItemMap.checkOut;
        const checkInMsg = menuItemMap.checkInMsg;
        const pkgStatus = app.activeProject?.config.onlineConfig?.packageStatus;
        const statusObj = pkgStatus[node.id] as CoworkPackageStatus;
        const user = app.global.user;
        const sameUser = app.activeProject?.config.onlineConfig.userId === user?.id;
        // 判断项目权限
        const projectPermission = await coworkService.getProjectPermission(app.activeProject?.id);
        if (!user || node.data.isOnlineNew || !sameUser || !projectPermission) {
          checkIn.disabled = true;
          checkOut.disabled = true;
        } else {
          if (!statusObj) {
            // 没有包状态可能是退出登录了，所有状态被清空，或者包状态未加载成功
            checkIn.disabled = true;
            checkOut.disabled = true;
          } else {
            if (statusObj.READ_PERMISSION === ReadPermissionType.R || statusObj.LOCKED || statusObj.APPROVAL_STATUS) {
              // 无权限
              checkIn.disabled = true;
              checkOut.disabled = true;
            } else if (statusObj.CHECKED_IN) {
              // 已锁定编辑，锁定编辑禁用，解锁可用
              checkIn.disabled = true;
              checkOut.disabled = false;
            } else if (!statusObj.CHECKED_IN) {
              // 未锁定编辑，锁定编辑可用，解锁禁用
              checkIn.disabled = false;
              checkOut.disabled = true;
            }
          }
        }

        if (!user || !sameUser) {
          checkInMsg.disabled = true;
        }
        // 如用户有父包的读写权限，没有子包的读写权限，或仅有部分子包的读写权限。则用户在锁定编辑父包时，置灰递归锁定编辑
        // if (!checkIn.disabled) {
        //   const checkInPackageAll = menuItemMap.checkInPackageAll;
        //   // 获取所有子包
        //   const allPackageIds: string[] = await modelHttp.get(API.MODEL_SERVICE_MODEL_FETCH_ALL_PACKAGES, {
        //     projectId: node.project.id,
        //     modelId: node.id
        //   }).then((res) => res.data as string[]);
        //   // 获取所有包状态
        //   const packageStatus = node.project.config.onlineConfig.packageStatus;
        //   for (let packageId of allPackageIds) {
        //     // 如果有可见且只读的包则不让递归。不可见的后面锁定编辑的时候会过滤掉不可见的包
        //     if (!packageStatus[packageId] || (packageStatus[packageId].VISIBILITY && packageStatus[packageId].READ_PERMISSION === READ_PERMISSION_TYPE.R)) {
        //       checkInPackageAll.disabled = true;
        //       break;
        //     }
        //   }
        // }
      }
    }

    return menuItems;
  }

  modifyEncryptMenu(menuItemMap: Record<string, MenuItem>, menuItems: MenuItem[], node: GraphNode) {
    if (node.data?.isEncrypted || node.data?.hiddenStatus === HiddenStatus.SHOW_IN_ENCAP) {
      menuItemMap.copyNode.disabled = true;
      menuItemMap.cutNode.disabled = true;
      if (menuItemMap.export) menuItemMap.export.disabled = true;
    }
    return menuItems;
  }

  modifyPackageMenu(menuItemMap: Record<string, MenuItem>, menuItems: MenuItem[], node: GraphNode) {
    // 处理Package和Model的导出profile禁用
    if ((node.data.metaclass === MetaclassType.Model || node.data.metaclass === MetaclassType.Package) && menuItemMap.export?.children) {
      menuItemMap.export.children.removeBy(it => it.value === ActionKey.exportProfile);
    }
    if (node.data.metaclass === MetaclassType.Model && menuItemMap.export?.children) {
      menuItemMap.export.children.removeBy(it => it.value === ActionKey.distributeProject);
    }
    if (!node.data.ownerId && menuItemMap.export?.children) {
      // 根节点不显示导出项目*.md3
      menuItemMap.export.children.removeBy(it => it.value === ActionKey.exportMd3);
    }

    // 处理Model删除的禁用
    if (node.data.metaclass == MetaclassType.Model && !node.parentId) {
      menuItemMap.removeModel.disabled = true;
    }

    if (node.data.metaclass === MetaclassType.Profile) {
      const item = menuItemMap.export?.children?.find((it: MenuItem) => it.value === ActionKey.exportProfile);
      if (item) {
        if (node.data?.from !== ModelFrom.USER_CREATE) {
          item.disabled = true;
        }
      }
    }
    return menuItems;
  }
  // 判断节点极其父节点的usedStatus值，即是否是主动使用包（2）和恢复元素（3）
  validNodeUsedStatusValue(node: GraphNode, usedStatusValue: UsedStatus[]) {
    if (node.data.usedStatus && usedStatusValue.includes(node.data.usedStatus)) {
      return true;
    } else if (app.activeProject && node.data.ownerId) {
      const parentNode = app.activeProject?.nodePool.getNode(node.data.ownerId);
      return parentNode && this.validNodeUsedStatusValue(parentNode, usedStatusValue);
    }
    return false;
  }
  modifyModelSharedMenu(menuItems: MenuItem[], node: GraphNode) {
    if (isShowShareValid()) {
      const ui = app.activeProject!.ui;
      const value = this.validNodeUsedStatusValue(node, [UsedStatus.STATUS_USED]); // 判断是否是使用包
      // 协同项目下
      const { online } = app.activeProject!.config;
      let disable = false;
      if (online) {
        disable = !app.activeProject || !app.activeProject?.nodePool?.rootNodes[0] || app.activeProject?.nodePool?.rootNodes[0].disabled;
        if (disable) {
          menuItems = menuItems.filter(item => item.value !== "projectUse");
        }
      }
      if (value) {
        const isUsagePkg = ui.usagePackageMap.get(node.id);
        const isDirectUsagePkg = ui.usagePackageMap.get(node.id)?.directUsage;
        if (!isUsagePkg) {
          menuItems = menuItems.filter(it => it.value !== "projectUse");
          menuItems.forEach(one => {
            if (!["navTo", "openFile", "saveAsFile"].includes(one.value)) {
              one.disabled = true;
            }
          });
        } else {
          menuItems.forEach(one => {
            if (one.value === "projectUse") {
              one.disabled = disable;
              one.children &&
                one.children?.push(
                  {
                    label: "移除",
                    value: ActionKey.RemoveUseProject,
                    disabled: !isDirectUsagePkg
                  },
                  {
                    label: "重新加载",
                    value: ActionKey.ReloadUseProject,
                    disabled: !isDirectUsagePkg
                  },
                  {
                    label: "更换项目",
                    value: ActionKey.ReplaceUseProject,
                    disabled: !isDirectUsagePkg
                  },
                  {
                    label: "打开项目",
                    value: ActionKey.OpenUseProject
                  }
                );
              // 共享项目需要新增编辑入口
              if (node.project?.config?.online) {
                one.children &&
                  one.children.push({
                    label: "编辑项目",
                    value: ActionKey.EditUseProject
                  });
              }
              if (!app.activeProject?.config.online) {
                one.children &&
                  one.children?.push({
                    label: "打开文件位置",
                    value: ActionKey.OpenUseProjectPath
                  });
              } else if (isDirectUsagePkg && !disable) {
                one.children &&
                  one.children.push({
                    label: "集成离线项目",
                    value: ActionKey.IntegrateLocalProject
                  });
              }
              if (isDirectUsagePkg && !disable) {
                one.children &&
                  one.children.push({
                    label: "转为项目元素",
                    value: ActionKey.ConvertToProjectElements
                  });
              }
            } else if (!["navTo", "openFile", "saveAsFile"].includes(one.value)) {
              one.disabled = true;
            }
          });
        }
      } else {
        const newValue = this.validNodeUsedStatusValue(node, [UsedStatus.STATUS_RESUME, UsedStatus.STATUS_AGENT]); // 判断是否是恢复元素和代理元素
        if (newValue) {
          menuItems.forEach(one => {
            if (!["navTo", "removeModel"].includes(one.value)) {
              one.disabled = true;
            }
          });
        }
      }
    } else {
      const index = menuItems.findIndex(one => one.value === "projectUse");
      if (index > -1) {
        menuItems.splice(index, 1);
      }
    }
  }
  modifySimulateMenu(menuItems: MenuItem[], node: GraphNode) {
    menuItems = menuItems?.filter(item => item && item?.value !== "simulate"); // 仿真的全部去除，由插件提供菜单
    // sim-ui except encrypt
    if (node.data.baseSt?.includes("UIPrototyping")) {
      menuItems = menuItems.filter(item => item && item?.value !== "encryptModel");
    }
    return menuItems;
  }

  setDisabled(menuItemMap: Record<string, MenuItem>, menuItems: MenuItem[], node: GraphNode) {
    if (node.disabled) {
      treeForEach(menuItems, it => {
        if (it.disabledWhenReadonly) {
          // 下发流程通过，项目仍然禁用，但是下发按钮可以点击
          if (app.activeProject?.coworkApprovalStatus.distributePackageId === node.id && it.value === "distributeProject") {
            it.disabled = false;
          } else if (app.activeProject?.coworkApprovalStatus.integrateProjectId && it.value === "projectUse") {
            const usagePackage = app.activeProject?.ui.usagePackageMap.get(node.id);
            if (
              usagePackage &&
              usagePackage.directUsage &&
              usagePackage.usageProjectId === app.activeProject?.coworkApprovalStatus.integrateProjectId
            ) {
              it.disabled = false;
              it.children = [
                {
                  label: "集成离线项目",
                  value: ActionKey.IntegrateLocalProject
                }
              ];
            }
          } else {
            it.disabled = true;
          }
        }
      });
    }
    return menuItems;
  }

  tipModelUnVisible(modelName?: string | string[]) {
    let tip = Array.isArray(modelName) ? modelName.map(name => name || "").join("、") : modelName || "";
    app.$notify({ title: "提示", message: "模型 " + tip + " 处于不可见包中", type: "warning" });
  }
  isPackageVisible(data: ModelData, online: boolean, packageStatusMap: PackageStatusObject) {
    if (online) {
      if (data.isOnlineNew) {
        // 新建的可见
        return true;
      }
      if (!data.ownerId) {
        return true;
      }
      if (data.from !== ModelFrom.USER_CREATE) return true;
      // 找到所在的包
      // const firstPkg = modelUtil.isPackage(this.data.metaclass) ? this : this.getFirstPackageOwner();
      // if (!firstPkg) return true;

      // 新建的可见
      // if (firstPkg?.data?.isOnlineNew) return true;
      // 不是新建的包应该在cowork服务器上有记录,判断packageStatus
      const packageStatus = packageStatusMap[data.id];

      return packageStatus ? packageStatus.VISIBILITY && packageStatus.secretVisible : true;
    } else if (data?.hiddenStatus === HiddenStatus.HIDDEN_IN_ENCAP) {
      return false;
    }
    return true;
  }
  // 设置定位批注按钮
  modifyLocateComment(menuItemMap: Record<string, MenuItem>, menuItems: MenuItem[], commentLevel?: number) {
    if (!menuItemMap?.LocateComment) return menuItems;
    // 非协同项目移除定位批注按钮
    if (!app.activeProject?.config.online) {
      menuItems = menuItems.filter(v => v.value !== "LocateComment");
      return menuItems;
    }

    const isShowComment = app.projectManager.activeProject?.ui.isShowComment;
    if (!isShowComment || (commentLevel ?? -1) === -1) {
      menuItemMap.LocateComment.disabled = true;
    }
    return menuItems;
  }
  // async modifyModelicaMenu(menuItemMap: Record<string, MenuItem>, menuItems: MenuItem[], node: GraphNode) {
  //   // try {
  //   //   const validModelFromMoModel = await mLinkService.validModelFromMoModel(app.activeProject!.id, node.id);
  //   //   if (validModelFromMoModel) {
  //   //     menuItems = menuItems?.filter(v => v.value === 'removeModel');
  //   //   }
  //   // } catch (error) {
  //   //   console.error(error);
  //   // }
  //   return menuItems;
  // }
}

export const treeUtil = new TreeUtil();
